home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PRINTER / JPSRC11.ARJ / JETPRD.C < prev    next >
C/C++ Source or Header  |  1991-08-04  |  9KB  |  335 lines

  1. /*
  2.  *      JET PAK - HP DeskJet and LaserJet series printer utilities
  3.  *
  4.  *      JETPRD program - output Printer Description file
  5.  *
  6.  *      Version 1.1 (Public Domain)
  7.  */
  8.  
  9. /* system include files */
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13.  
  14. /* application include files */
  15. #include "patchlev.h"
  16. #include "jetfont.h"
  17. #include "jetutil.h"
  18.  
  19. /*
  20.  *  MODULE GLOBAL DATA
  21.  */
  22.  
  23. /* input command being processed */
  24. static FONT_COMMAND fc;
  25.  
  26. /* character code being processed */
  27. static UNSIGNEDINT charcode;
  28.  
  29. /* pitch required for character widths in fixed fonts */
  30. static UNSIGNEDINT pitch;
  31.  
  32. /* output file suffix */
  33. static char output_suffix[SUFFIX_MAX] = ".prd";
  34.  
  35. /*
  36.  * LOCAL FUNCTIONS
  37.  */
  38.  
  39. static void usage_wrong()
  40. {
  41.     /*
  42.      * Print usage message and exit.
  43.      */
  44.     fprintf(stderr, USAGE_HEADER);
  45.     fprintf(stderr, "Usage: JETPRD [-h] [-t filetype] fontfile [fontfile...]\n\n");
  46.     fprintf(stderr, "Output Printer Descriptor files for soft fonts\n\n");
  47.     fprintf(stderr, "  -h            print this usage information\n");
  48.     fprintf(stderr, "  -t filetype   change output file type (default %s)\n", output_suffix);
  49.     fprintf(stderr, "  fontfile      soft font file name\n");
  50.     exit(1);
  51. }
  52.  
  53. static int printisd(fp, i)
  54. FILE *fp;
  55. UNSIGNEDINT i;
  56. {
  57.     /*
  58.      *  Convert an integer to a string, then output each byte
  59.      *  separately in decimal
  60.      */
  61.     char s[20], *sp = s;
  62.  
  63.     sprintf(s, "%d", i);
  64.  
  65.     while (*sp)
  66.     {
  67.         if (fprintf(fp, "%d", *sp) < 0)
  68.             return(ERROR);
  69.         if (*(++sp))
  70.             if (fprintf(fp, ",") < 0)
  71.                 return(ERROR);
  72.     }
  73.  
  74.     return(OK);
  75. }
  76.  
  77. static int printfsd(fp, f)
  78. FILE *fp;
  79. float f;
  80. {
  81.     /*
  82.      *  Convert a float to a string, then output each byte
  83.      *  separately in decimal
  84.      */
  85.     char s[20], *sp = s;
  86.  
  87.     sprintf(s, "%.2f", f);
  88.  
  89.     while (*sp)
  90.     {
  91.         if (fprintf(fp, "%d", *sp) < 0)
  92.             return(ERROR);
  93.         if (*(++sp))
  94.             if (fprintf(fp, ",") < 0)
  95.                 return(ERROR);
  96.     }
  97.  
  98.     return(OK);
  99. }
  100.  
  101. static int headerprint(fp)
  102. FILE *fp;
  103. {
  104.     /*
  105.      * Output the escape sequence required to select the font unambiguously
  106.      */
  107.  
  108.     /* orientation */
  109.     if (fprintf(fp, "27,38,108,") < 0)
  110.         return(ERROR);
  111.     if (printisd(fp, fc.data.font.orientation) == ERROR)
  112.         return(ERROR);
  113.     if (fprintf(fp, ",79,") < 0)
  114.         return(ERROR);
  115.  
  116.     /* character set */
  117.     if (fprintf(fp, "27,40,") < 0)
  118.         return(ERROR);
  119.     if (printisd(fp, fc.data.font.symbol_set/32) == ERROR)
  120.         return(ERROR);
  121.     if (fprintf(fp, ",%d", '@'+fc.data.font.symbol_set%32) < 0)
  122.         return(ERROR);
  123.  
  124.     /* spacing */
  125.     if (fprintf(fp, ",27,40,115,") < 0)
  126.         return(ERROR);
  127.     if (printisd(fp, fc.data.font.spacing) == ERROR)
  128.         return(ERROR);
  129.     if (fprintf(fp, ",112,") < 0)
  130.         return(ERROR);
  131.  
  132.     /* pitch required for fixed pitch fonts only */
  133.     if (fc.data.font.spacing == FIXED)
  134.     {
  135.         if (printfsd(fp, quarter_dots_to_lpi(fc.data.font.pitch)) == ERROR)
  136.             return(ERROR);
  137.         if (fprintf(fp, ",104,") < 0)
  138.             return(ERROR);
  139.     }
  140.  
  141.     /* point size */
  142.     if (printisd(fp, (UNSIGNEDINT)(0.5+quarter_dots_to_points(fc.data.font.height))) == ERROR)
  143.         return(ERROR);
  144.     if (fprintf(fp, ",118,") < 0)
  145.         return(ERROR);
  146.  
  147.     /* type style */
  148.     if (printisd(fp, fc.data.font.style) == ERROR)
  149.         return(ERROR);
  150.     if (fprintf(fp, ",115,") < 0)
  151.         return(ERROR);
  152.  
  153.     /* stroke weight */
  154.     if (printisd(fp, fc.data.font.stroke_weight) == ERROR)
  155.         return(ERROR);
  156.     if (fprintf(fp, ",98,") < 0)
  157.         return(ERROR);
  158.  
  159.     /* type face */
  160.     if (printisd(fp, fc.data.font.typeface) == ERROR)
  161.         return(ERROR);
  162.     if (fprintf(fp, ",116,") < 0)
  163.         return(ERROR);
  164.  
  165.     /* quality */
  166.     if (printisd(fp, fc.data.font.quality) == ERROR)
  167.         return(ERROR);
  168.     if (fprintf(fp, ",81\n") < 0)
  169.         return(ERROR);
  170.  
  171.     /* print width of space (same as pitch) in 300dpi units */
  172.     if (fprintf(fp, "%d=%d\n", ' ', fc.data.font.pitch / 4) < 0)
  173.         return(ERROR);
  174.  
  175.     /* save pitch for fixed width fonts (0 indicates proportional font) */
  176.     if (fc.data.font.spacing == FIXED)
  177.         pitch = fc.data.font.pitch / 4;
  178.     else
  179.         pitch = 0;
  180.  
  181.     return(OK);
  182. }
  183.  
  184. static int widthprint(fp)
  185. FILE *fp;
  186. {
  187.     /*
  188.      * Output the width information for a single character
  189.      */
  190.  
  191.     switch (fc.data.character.format)
  192.     {
  193.     default:
  194.         fprintf(stderr, WARNING_BAD_CHAR_FORMAT,
  195.                     os_dir, os_file, fc.data.character.format);
  196.  
  197.         /* !! INTENTIONAL DROP-THROUGH !! */
  198.  
  199.     case LJCHARFORMAT:
  200.         if (fprintf(fp, "%d=%d\n", charcode, (pitch > 0) ? (int)pitch :
  201.                     (int)(fc.data.character.data.ljchar.delta_x/4)) < 0)
  202.             return(ERROR);
  203.         break;
  204.     case DJCHARFORMAT:
  205.     case DJPCHARFORMAT:
  206.     case DJ500CHARFORMAT:
  207.         /* only print the data in the first pass */
  208.         if (pass_for_char_type(fc.data.character.data.djchar.char_type) == 0)
  209.             if (fprintf(fp, "%d=%d\n", charcode, (pitch > 0) ? (int)pitch :
  210.                     (   (int)fc.data.character.data.djchar.character_width
  211.                       + (int)fc.data.character.data.djchar.left_offset
  212.                       + (int)fc.data.character.data.djchar.right_offset)/2) < 0)
  213.                 return(ERROR);
  214.         break;
  215.     }
  216.  
  217.     return(OK);
  218. }
  219.  
  220. static void jetprd()
  221. {
  222.     char inpath[OS_PATH_LEN], outpath[OS_PATH_LEN], *sp;
  223.     FILE *infp, *outfp;
  224.     int r, fdc_found = FALSE;
  225.  
  226.     /* build the input and output file paths */
  227.     strcpy(inpath, os_dir);
  228.     strcat(inpath, os_file);
  229.     strcpy(outpath, os_file);
  230.     if ((sp = strrchr(outpath, '.')) == NULL)
  231.         strcat(outpath, output_suffix);
  232.     else
  233.         strcpy(sp, output_suffix);
  234.  
  235.     /* rudimentary check for input overwriting output */
  236.     if (strcmp(inpath, outpath) == 0)
  237.     {
  238.         fprintf(stderr, ERROR_OVERWRITE, os_dir, os_file);
  239.         return;
  240.     }
  241.  
  242.     if (!(infp = fopen(inpath, "rb")))
  243.     {
  244.         fprintf(stderr, ERROR_OPEN_READ_FAILED, os_dir, os_file);
  245.         return;
  246.     }
  247.     if (!(outfp = fopen(outpath, "w")))
  248.     {
  249.         fprintf(stderr, ERROR_OPEN_WRITE_FAILED, os_dir, os_file, outpath);
  250.         fclose(infp);
  251.         return;
  252.     }
  253.  
  254.     while ((r = font_command_read(infp, &fc)) == OK)
  255.     {
  256.         switch(fc.command_type)
  257.         {
  258.         case FDC:
  259.             if (headerprint(outfp) == ERROR)
  260.             {
  261.                 fprintf(stderr, ERROR_FILE_WRITE_FAILED, os_dir, os_file);
  262.                 fclose(infp);
  263.                 fclose(outfp);
  264.                 return;
  265.             }
  266.  
  267.             fdc_found = TRUE;
  268.  
  269.             break;
  270.         case CCC:
  271.             charcode = fc.number;
  272.             break;
  273.         case CDC:
  274.             if (widthprint(outfp) == ERROR)
  275.             {
  276.                 fprintf(stderr, ERROR_FILE_WRITE_FAILED, os_dir, os_file);
  277.                 fclose(infp);
  278.                 fclose(outfp);
  279.                 return;
  280.             }
  281.             break;
  282.         }
  283.     }
  284.  
  285.  
  286.     /* error scenarios: (!fdc_found) means no font descriptor found,
  287.        probably processing a text file; (r != EOF) means a font
  288.        command escape sequence wasn't read in correctly, probably
  289.        processing a binary file or a truncated soft font file */
  290.     if (!fdc_found || r != EOF)
  291.         fprintf(stderr, ERROR_FILE_READ_FAILED, os_dir, os_file);
  292.     else
  293.         fprintf(stderr, OK_JETPRD, os_dir, os_file, outpath);
  294.  
  295.     fclose(infp);
  296.     fclose(outfp);
  297. }
  298.  
  299. main(argc, argv)
  300. int argc;
  301. char *argv[];
  302. {
  303.     char c;
  304.  
  305.     /* stop getopt() printing errors */
  306.     opterr = FALSE;
  307.     while ((c = getopt(argc, argv, "t:h")) != EOF)
  308.     {
  309.         switch (c)
  310.         {
  311.         case 't':
  312.             strncpy(output_suffix+1, optarg, SUFFIX_MAX-2);
  313.             output_suffix[SUFFIX_MAX-1] = '\0';
  314.             break;
  315.         case 'h':
  316.         case '?':
  317.             /* help required, or invalid option specified */
  318.             usage_wrong();
  319.         }
  320.     }
  321.  
  322.     /* must specify at least one file */
  323.     if (optind >= argc)
  324.         usage_wrong();
  325.  
  326.     /* process file arguments */
  327.     if (os_findfiles((argc - optind), &argv[optind]) == ERROR)
  328.         fprintf(stderr, ERROR_OUT_OF_HEAP);
  329.  
  330.     while (os_getfile() != EOF)
  331.         jetprd();
  332.  
  333.     return(0);
  334. }
  335.